package com.example.templateapp.util

import android.app.Application
import android.util.Log
import android.widget.ProgressBar
import android.widget.TextView
import androidx.appcompat.app.AlertDialog
import androidx.appcompat.app.AppCompatActivity
import com.alibaba.fastjson.JSON
import com.example.templateapp.R
import com.xuexiang.xupdate.XUpdate
import com.xuexiang.xupdate._XUpdate
import com.xuexiang.xupdate.entity.UpdateEntity
import com.xuexiang.xupdate.proxy.IUpdateHttpService
import com.xuexiang.xupdate.service.OnFileDownloadListener
import com.xuexiang.xupdate.utils.UpdateUtils
import com.xuexiang.xutil.app.PathUtils
import com.xuexiang.xutil.file.FileIOUtils
import com.xuexiang.xutil.file.FileUtils
import com.xuexiang.xutil.tip.ToastUtils
import io.reactivex.rxjava3.android.schedulers.AndroidSchedulers
import rxhttp.toDownload
import rxhttp.wrapper.param.RxHttp
import java.io.File
import kotlin.math.roundToInt

/*
* 	implementation 'com.github.xuexiangjys.XUtil:xutil-sub:1.1.7'
*   implementation 'com.github.xuexiangjys:XUpdate:1.1.4'
*
*   R.layout.update_dialog
*
* */

class UpdateUtil {
    companion object {

        const val mUrl = "https://tmsway.oss-cn-beijing.aliyuncs.com/jingye/"

        const val mFileName = ".txt"

        fun init(isDebug: Boolean, context: Application) {
            XUpdate.get()
                .debug(isDebug)
                .isWifiOnly(false)
                .isGet(true)
                .setIUpdateHttpService(XHttpUpdateHttpService())
                .init(context)
        }

        suspend fun update(context: AppCompatActivity, fileName: String = mFileName) {
            if (mFileName.startsWith(".")) return
            val filePath = RxHttp.get(fileName)
                .setUrl(mUrl + fileName)
                .toDownload(PathUtils.getAppExtFilePath() + "/" + fileName)
                .await()

            getFile(filePath, context)
        }

        private fun getFile(filePath: String, context: AppCompatActivity) {
            val file = File(filePath)
            if (FileUtils.isFileExists(file)) {
                val s = FileIOUtils.readFile2String(file)
                Log.d("updateContent", s)
                if (s.isNotBlank()) parseContentDoUpdate(s, context)
            }
        }

        private fun parseContentDoUpdate(s: String, context: AppCompatActivity) {
            val jobj = JSON.parseObject(s)
            val versionCode = jobj.getIntValue("versionCode")
            val versionName = jobj.getString("versionName")
            val illustrate = jobj.getString("illustrate")
            val url = jobj.getString("url")

            val updateEntity = UpdateEntity()
            updateEntity.versionCode = versionCode
            updateEntity.versionName = versionName
            updateEntity.updateContent = illustrate
            updateEntity.downloadUrl = url

            updateEntity.downLoadEntity.isShowNotification = true
            val hasUpdate = versionCode > UpdateUtils.getVersionCode(context)
            updateEntity.isHasUpdate = hasUpdate

            if (hasUpdate) {
                showUpdatePrompt(context, updateEntity)
            }
        }

        private fun showUpdatePrompt(context: AppCompatActivity, updateEntity: UpdateEntity) {
            val dialogBuilder = AlertDialog.Builder(context)
            dialogBuilder.setIcon(R.mipmap.ic_launcher_round)
            dialogBuilder.setTitle("更新提示：")
            dialogBuilder.setMessage(updateEntity.updateContent)
            dialogBuilder.setCancelable(false)

            dialogBuilder.setPositiveButton(
                "去更新"
            ) { dialog, _ ->
                dialog.dismiss()
                downloadApk(context, updateEntity.downloadUrl)
            }

            dialogBuilder
                .create()
                .also {
                    it.setCanceledOnTouchOutside(false)
                    it.show()
                }
        }

        private fun downloadApk(context: AppCompatActivity, downloadUrl: String?) {
            val progressDialog =
                AlertDialog.Builder(context)
                    .setView(R.layout.dialog_progress)
                    .setCancelable(false)
                    .create()
                    .also {
                        it.setCanceledOnTouchOutside(false)
                        it.show()
                    }
            val progressBar = progressDialog.findViewById<ProgressBar>(R.id.progress)
            val progressTv = progressDialog.findViewById<TextView>(R.id.progress_tv)

            XUpdate.newBuild(context)
                .apkCacheDir(PathUtils.getAppExtFilePath())
                .build()
                .download(downloadUrl, object : OnFileDownloadListener {
                    override fun onProgress(progress: Float, total: Long) {
                        val progressInt = (progress * 100).roundToInt()
                        progressBar?.progress = progressInt
                        progressTv?.text = "$progressInt%"
                    }

                    override fun onError(throwable: Throwable?) {
                        progressDialog.dismiss()
                        ToastUtils.toast("下载失败")
                        context.finish()
                    }

                    override fun onStart() {}

                    override fun onCompleted(file: File?): Boolean {
                        progressDialog.dismiss()
                        _XUpdate.startInstallApk(context, file!!)
                        return false
                    }
                })
        }
    }

    class XHttpUpdateHttpService : IUpdateHttpService {
        override fun download(
            url: String,
            path: String,
            fileName: String,
            callback: IUpdateHttpService.DownloadCallback
        ) {
            RxHttp.get("")
                .setUrl(url)
                .asDownload(path + fileName, {
                    callback.onProgress(it.currentSize.div(it.totalSize.toFloat()), it.totalSize)
                }, AndroidSchedulers.mainThread())
                .subscribe({
                    callback.onSuccess(File(it))
                }, {
                    callback.onError(it)
                })

        }

        override fun asyncGet(
            url: String,
            params: MutableMap<String, Any>,
            callBack: IUpdateHttpService.Callback
        ) {

            RxHttp.get("")
                .setUrl(url)
                .asString()
                .subscribe({
                    callBack.onSuccess(it)
                }, {
                    callBack.onError(it)
                })

        }

        override fun cancelDownload(url: String) {
            ToastUtils.toast("已取消更新")
        }

        override fun asyncPost(
            url: String,
            params: MutableMap<String, Any>,
            callBack: IUpdateHttpService.Callback
        ) {
            RxHttp.postJson("")
                .setUrl(url)
                .asString()
                .subscribe({
                    callBack.onSuccess(it)
                }, {
                    callBack.onError(it)
                })
        }
    }

}